from collections import Iterable

from common.constant import QuestionType
from common.compute_unit import *
import json
from common.documents import Question, APIModel

success_condition = {
    # ('retcode',): lambda x: int(x) >= 0
}

success_c = verify_success(success_condition)
solvers = {}
with solvers_register(QuestionType.IS_LOGIN, solvers) as s:
    s.cal_flow = Source(url='url').my_filter(success_c).update(remove_headers).update(resend).summary(
        my_all(my_not(success_c)))
    s.res_builder = lambda md, res: json.dumps(res)

with solvers_register(QuestionType.ABOUT_SQL, solvers) as s:
    s.cal_flow = Source(url='url').my_filter(success_c).update(resend).listen(remember_sql)
    s.res_builder = lambda md, res: json.dumps(md.aboutSql)

with solvers_register(QuestionType.PARAM_IS_NECESSARY, solvers) as s:
    s.condition = lambda model: model.only_selected()
    s.cal_flow = Source(url='url').my_filter(success_c).expand(remove_one_required).my_filter(
        no_checked_param).update(resend).my_filter(success_c).expand(update_required)
    s.res_builder = lambda md, res: json.dumps(res)

with solvers_register(QuestionType.PARAM_HAS_GROUP, solvers) as s:
    s.condition = lambda model: model.only_selected()
    s.cal_flow = Source(url='url').my_filter(success_c).model_update(remove_all_group).update(
        remove_not_required).update(resend).summary(my_all(my_not(success_c))).IF(
        success=Source(url='url').expand(one_not_required)).update(resend).summary(summary_group(success_c))
    s.res_builder = lambda md, res: json.dumps(list(res))

with solvers_register(QuestionType.PARAM_TYPE, solvers) as s:
    s.condition = lambda model: model.only_selected()
    s.cal_flow = Source(url='url').my_filter(success_c).gate(get_all_routes_and_values).update(summarize_param_type)
    s.res_builder = lambda md, res: json.dumps(list(res))

sol_order = [QuestionType.PARAM_TYPE,QuestionType.ABOUT_SQL, QuestionType.IS_LOGIN, QuestionType.PARAM_IS_NECESSARY,
             QuestionType.PARAM_HAS_GROUP]


def solve_one_problem(question):
    model = APIModel.objects(url=question.about).first()
    if not model or model.is_ignored():
        return
    if question.que_type in solvers:
        solvs = solvers[question.que_type]
        for solv in solvs:
            if not solv.condition(model):
                continue
            res = solv.cal_flow(model)
            if isinstance(res, Iterable):
                res = list(res)
            question.result = solv.res_builder(model, res)
            question.solved = True
            question.save()
            break


def solve_problem(url=None):
    """
    自动解决问题
    :return:
    """
    from common.documents import QuestionState

    for order in sol_order:
        que_state = QuestionState.objects(que_type=order).first()
        if not (que_state and que_state.auto_solve_available):
            continue
        if url is None:
            ite = Question.objects(que_type=order, solved=False)
        else:
            ite = Question.objects(que_type=order, solved=False, about=url)
        for question in ite:
            solve_one_problem(question)
